package com.gitee.wsl.time.schedule.ext

import com.gitee.wsl.ext.base.currentTime
import com.gitee.wsl.time.millisecondsLong
import com.gitee.wsl.time.schedule.TimeScheduler
import kotlinx.coroutines.delay
import kotlin.time.ExperimentalTime
import kotlin.time.Instant

/**
 * Execute [block] once at the [KronScheduler.next] time and return result of [block] calculation.
 *
 * WARNING!!! If you want to launch it in parallel, you must do this explicitly.
 *
 * WARNING!!! In case if [KronScheduler.next] of [this] instance will return null, [block] will be called immediately
 */
 @OptIn(ExperimentalTime::class)
 suspend inline fun <T> TimeScheduler.doOnce(block: (Instant) -> T): T {
    val time = nextOrNow().also {
        delay((it - currentTime).millisecondsLong)
    }
    return block(time)
}